package com.gopay.bis.service.bank.validcode;

import java.util.Date;
import java.util.HashMap;
import java.util.Map;

import javax.annotation.Resource;

import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import com.gopay.bis.dao.payconfig.BisExpaySmsSendLogDAO;
import com.gopay.bis.manager.bank.payconfig.SmsSupportService;
import com.gopay.bis.manager.bank.payconfig.ValidCodeSupportService;
import com.gopay.common.constants.bank.SmsSendSourceConstants;
import com.gopay.common.constants.cust.SMSType;
import com.gopay.common.constants.proccode.ProcCodeConstants;
import com.gopay.common.cps.manager.order.CpsGeneralMainOrderQueryManager;
import com.gopay.common.domain.bank.ExPayBaseMessage;
import com.gopay.common.domain.cps.CpsGenMainOrder;
import com.gopay.common.domain.ep.EpCardStatus;
import com.gopay.common.domain.log.BisExpaySmsSendLog;
import com.gopay.common.exception.GopayException;
import com.gopay.remote.cps.expresspay.EpBankCardRemoteService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class ValidCodeSupportController {
    @Resource(name = "cpsGeneralMainOrderQueryManager")
    private CpsGeneralMainOrderQueryManager mainOrderQuery;

    @Resource(name = "smsSupportService")
    private SmsSupportService smsSupportService;

    @Resource(name = "epBankCardService")
    protected EpBankCardRemoteService epBankCardService;

    @Resource(name = "validCodeSupportService")
    private ValidCodeSupportService validCodeSupportService;

    @Resource(name = "bisExpaySmsSendLogDAO")
    private BisExpaySmsSendLogDAO bisExpaySmsSendLogDAO;

    private static Logger logger = LoggerFactory.getLogger(ValidCodeSupportController.class);

    /**
     * 发送
     * 
     * @param bankPhoneNo
     * @param orderId
     * @return
     */
    public Map<String, String> createValidCode(ExPayBaseMessage baseMsg) {
        Map<String, String> resMap = new HashMap<String, String>();
        if (0 == baseMsg.getSenMaxCount()) {
            resMap.put("sendCount", "0");
            resMap.put("resCode", ProcCodeConstants.PROC_CODE_100E6092);
            resMap.put("retMsg", "发送短信最大次数为0");
            return resMap;
        }
        if (0 == baseMsg.getFailMaxCount()) {
            resMap.put("sendCount", "0");
            resMap.put("resCode", ProcCodeConstants.PROC_CODE_100E6097);
            resMap.put("retMsg", "验证短信失败最大次数为0");
            return resMap;
        }

        // 发送短信最大次数网关传送，按orderId查询
        int sendCount = smsSupportService.checkSendSmsCont(baseMsg.getOrderId());
        if ((sendCount > baseMsg.getSenMaxCount() - 1)) {
            resMap.put("sendCount", String.valueOf(sendCount));
            resMap.put("resCode", ProcCodeConstants.PROC_CODE_100E6094);
            resMap.put("retMsg", "获取次数超限，获取失败");
            return resMap;
        }

        // 查询该卡状态
        boolean isFreeze = epBankCardService.isFreezeCardNo(baseMsg.getCardNo());
        // 短信失败最大次数网关传送，按orderId查询
        int failCount = smsSupportService.checkFailSmsCount(baseMsg.getOrderId());
        if ((failCount > baseMsg.getFailMaxCount() - 1) && !isFreeze) {
            resMap.put("sendCount", String.valueOf(sendCount));
            resMap.put("resCode", ProcCodeConstants.PROC_CODE_100E6095);
            resMap.put("retMsg", "错误次数超限，获取失败");
            return resMap;
        }

        if (isFreeze) {
            resMap.put("sendCount", String.valueOf(sendCount));
            resMap.put("resCode", ProcCodeConstants.PROC_CODE_100E6100);
            resMap.put("retMsg", "当日错误次数超限，该卡已被锁定");
            return resMap;
        }
        String validCode = validCodeSupportService.createValidCode(baseMsg);
        if (validCode != null) {
            resMap.put("sendCount", String.valueOf(sendCount + 1));
            resMap.put("validCode", validCode);
            resMap.put("resCode", ProcCodeConstants.PROC_CODE_100E6102);
            resMap.put("retMsg", "短信发送成功");
            return resMap;
        } else {
            resMap.put("sendCount", String.valueOf(sendCount + 1));
            resMap.put("resCode", ProcCodeConstants.PROC_CODE_100E6096);
            resMap.put("retMsg", "获取短信验证码失败，请稍后再试");
            return resMap;
        }
    }

    /**
     * 验证
     * 
     * @param bankPhoneNo
     * @param verifyCode
     * @return
     */
    public Map<String, String> checkSMS(ExPayBaseMessage baseMsg) {
        Map<String, String> resMap = new HashMap<String, String>();
        int failMaxCount = baseMsg.getFailMaxCount();
        if (0 == failMaxCount) {
            resMap.put("failCount", "0");
            resMap.put("resCode", ProcCodeConstants.PROC_CODE_100E6097);
            resMap.put("retMsg", "验证短信失败最大次数为0");
            return resMap;
        }
        int failCount = smsSupportService.checkFailSmsCount(baseMsg.getOrderId());

        boolean isFreeze = epBankCardService.isFreezeCardNo(baseMsg.getCardNo());
        if (isFreeze) {
            resMap.put("failCount", String.valueOf(failCount));
            resMap.put("resCode", ProcCodeConstants.PROC_CODE_100E6100);
            resMap.put("retMsg", "当日错误次数超限，该卡已被锁定");
            return resMap;
        }

        if ((failCount > failMaxCount - 1)) {
            int sameOrderCardFailCount = smsSupportService.checkCardFailSmsCount(baseMsg.getOrderId(),
                    baseMsg.getCardNo());
            if (sameOrderCardFailCount == baseMsg.getFailMaxCount()) {
                resMap.put("failCount", String.valueOf(failCount));
                resMap.put("resCode", ProcCodeConstants.PROC_CODE_100E6100);
                resMap.put("retMsg", "当日错误次数超限，该卡已被锁定");
                return resMap;

            } else {
                resMap.put("failCount", String.valueOf(failCount));
                resMap.put("resCode", ProcCodeConstants.PROC_CODE_100E6099);
                resMap.put("retMsg", "当日错误次数超限，无法提交");
                return resMap;
            }

        }
        boolean checkRes = validCodeSupportService.checkSMS(baseMsg);
        if (checkRes) {
            resMap.put("failCount", String.valueOf(failCount));
            resMap.put("resCode", ProcCodeConstants.PROC_CODE_100E6091);
            resMap.put("retMsg", "短信验证码输入正确");
            return resMap;
        } else {
            resMap.put("failCount", String.valueOf(failCount + 1));
            resMap.put("resCode", ProcCodeConstants.PROC_CODE_100E6098);
            resMap.put("retMsg", "短信验证码错误，您还有" + (failMaxCount - failCount - 1) + "次机会");
            return resMap;
        }
    }

    /**
     * 冻卡操作
     * 
     * @param baseMsg
     * @return
     */
    public Map<String, String> freezeCard(ExPayBaseMessage baseMsg) {
        Map<String, String> resMap = new HashMap<String, String>();
        // 校验失败后，调用cps进行冻卡操作
        int failCount = smsSupportService.checkFailSmsCount(baseMsg.getOrderId());
        EpCardStatus epCardStatus = epBankCardService.errAccum4SMS(baseMsg.getCardNo());
        if (EpCardStatus.STATUS_FREEZE.equals(epCardStatus.getStatus())) {
            resMap.put("failCount", String.valueOf(failCount));
            resMap.put("resCode", ProcCodeConstants.PROC_CODE_100E6100);
            resMap.put("retMsg", "当日错误次数超限，该卡已被锁定");
            return resMap;
        } else if (failCount == baseMsg.getFailMaxCount()) {
            resMap.put("failCount", String.valueOf(failCount));
            resMap.put("resCode", ProcCodeConstants.PROC_CODE_100E6099);
            resMap.put("retMsg", "当日错误次数超限，无法提交");
            return resMap;
        }

        return null;

    }

    /**
     * 新增校验失败的日志
     * 
     * @param baseMsg
     * @return
     */
    public Map<String, String> buildSendLog(ExPayBaseMessage baseMsg, int sendCount) {
        Map<String, String> resMap = new HashMap<String, String>();
        BisExpaySmsSendLog log = new BisExpaySmsSendLog();
        Date date = new Date();
        log.setMobileNum(baseMsg.getMediaId());
        log.setModuleId(SMSType.CASHIER_SMS_SEND.value);
        log.setOrderId(baseMsg.getOrderId());
        log.setCardNo(baseMsg.getCardNo());
        log.setOperateSource(SmsSendSourceConstants.SEND_SOURCE_BANK);
        log.setCreatedTime(date);
        bisExpaySmsSendLogDAO.save(log);
        resMap.put("sendCount", String.valueOf(sendCount));
        resMap.put("resCode", ProcCodeConstants.PROC_CODE_100E6102);
        resMap.put("retMsg", "发送成功");
        return resMap;

    }

    /**
     * 新增校验失败的日志
     * 
     * @param baseMsg
     * @return
     */
    public Map<String, String> buildCheckLog(ExPayBaseMessage baseMsg, int failCount) {
        Map<String, String> resMap = new HashMap<String, String>();
        BisExpaySmsSendLog log = new BisExpaySmsSendLog();
        Date date = new Date();
        log.setMobileNum(baseMsg.getMediaId());
        log.setModuleId(SMSType.CASHIER_SMS_ERROR.value);
        log.setOrderId(baseMsg.getOrderId());
        log.setCardNo(baseMsg.getCardNo());
        log.setOperateSource(SmsSendSourceConstants.CHECK_SOURCE_BANK);
        log.setCreatedTime(date);
        bisExpaySmsSendLogDAO.save(log);
        resMap.put("failCount", String.valueOf(failCount + 1));
        resMap.put("resCode", ProcCodeConstants.PROC_CODE_100E6101);
        resMap.put("retMsg", "银行卡信息错误，您还有" + (baseMsg.getFailMaxCount() - failCount - 1) + "次机会");
        return resMap;

    }

    /**
     * @param orderId
     * @param nullException
     *            - true:如果CpsGenMainOrder为null，抛出异常；false:
     *            如果CpsGenMainOrder为null，返回null
     * @throws WebException
     */
    protected CpsGenMainOrder getMainOrder(String orderId, boolean nullException) throws GopayException {
        CpsGenMainOrder order = null;
        if (StringUtils.isBlank(orderId)) {
            // 如果orderId为空，需要返回null；
            logger.error("查询CpsGenMainOrder，订单号orderId为空！ ");
        } else {
            order = mainOrderQuery.get(orderId);
        }
        if (nullException) {
            if (null == order) {
                logger.error("找不到订单！order not exits! orderId=" + orderId);
                throw new GopayException(ProcCodeConstants.PROC_CODE_100E5041);
            } else {
                return order;
            }
        }
        return order;
    }

    public CpsGeneralMainOrderQueryManager getMainOrderQuery() {
        return mainOrderQuery;
    }

    public void setMainOrderQuery(CpsGeneralMainOrderQueryManager mainOrderQuery) {
        this.mainOrderQuery = mainOrderQuery;
    }

    public SmsSupportService getSmsSupportService() {
        return smsSupportService;
    }

    public void setSmsSupportService(SmsSupportService smsSupportService) {
        this.smsSupportService = smsSupportService;
    }

    public ValidCodeSupportService getValidCodeSupportService() {
        return validCodeSupportService;
    }

    public void setValidCodeSupportService(ValidCodeSupportService validCodeSupportService) {
        this.validCodeSupportService = validCodeSupportService;
    }

}
